package com.service.bracelet.common;


import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.service.bracelet.entity.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.TimeUnit;

/**
 * 浏览器缓存管理，缓存60分钟，超过60分钟系统自动释放，用户的token访问会超时
 */
public class BrowserCacheManager {

    private static Logger logger = LoggerFactory.getLogger(BrowserCacheManager.class);

    /**
     * 缓存项最大数量
     */
    private static final long GUAVA_CACHE_SIZE = 10000000;

    /**
     * 缓存时间：分钟
     */
    private static final long GUAVA_CACHE_TIME = 60;

    /**
     * 缓存操作对象
     */
    private static LoadingCache<String, User> GLOBAL_CACHE = null;

    static {
        try {
            GLOBAL_CACHE = loadCache(new CacheLoader<String, User>() {
                @Override
                public User load(String key) throws Exception {
                    return null;
                }
            });
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
    }

    /**
     * 全局缓存设置
     * <p>
     * 缓存项最大数量：100000
     * 缓存有效时间（天）：10
     *
     * @param cacheLoader
     * @return
     * @throws Exception
     */
    private static LoadingCache<String, User> loadCache(CacheLoader<String, User> cacheLoader) throws Exception {
        LoadingCache<String, User> cache = CacheBuilder.newBuilder()
                //缓存池大小，在缓存项接近该大小时， Guava开始回收旧的缓存项
                .maximumSize(GUAVA_CACHE_SIZE)
                //设置时间对象没有被读/写访问则对象从内存中删除(在另外的线程里面不定期维护)
                .expireAfterAccess(GUAVA_CACHE_TIME, TimeUnit.MINUTES)
                // 设置缓存在写入之后 设定时间 后失效
                .expireAfterWrite(GUAVA_CACHE_TIME, TimeUnit.MINUTES)
                .build(cacheLoader);
        return cache;
    }

    /**
     * 设置缓存值
     * 注: 若已有该key值，则会先移除(会触发removalListener移除监听器)，再添加
     *
     * @param key
     * @param value
     */
    public static void put(String key, User value) {
        try {
            GLOBAL_CACHE.put(key, value);
        } catch (Exception e) {
        }
    }

    /**
     * 获取缓存值
     * 注：如果键不存在值，将调用CacheLoader的load方法加载新值到该键中
     *
     * @param key
     * @return
     */
    public static User get(String key) {
        User token = null;
        try {
            token = GLOBAL_CACHE.get(key);
            if (token != null) {
                GLOBAL_CACHE.put(key, token);
            }
        } catch (Exception e) {
        }
        return token;
    }

    /**
     * 移除cache内容
     *
     * @param key
     * @return
     */
    public static void remove(String key) {
        try {
            GLOBAL_CACHE.invalidate(key);
        } catch (Exception e) {
        }
    }
}
